﻿Imports System.Runtime.CompilerServices

Partial Public Class PublisherData
	Implements IEquatable(Of PublisherData)
	'Implements IEqualityComparer(Of PublisherData)

	Private Shared lastCalTime As DateTime

	Public Overrides Function Equals(other As Object) As Boolean
		Return Equals(TryCast(other, PublisherData))
	End Function

	Public Overloads Function Equals(other As PublisherData) As Boolean Implements IEquatable(Of SecretaryToolData.PublisherData).Equals
		If other Is Nothing Then
			Return False
		Else
			Return Me.PublisherID = other.PublisherID
		End If
	End Function

	Public Overloads Function Equals(this As PublisherData, that As PublisherData) As Boolean 'Implements IEqualityComparer(Of SecretaryToolData.PublisherData).Equals
		If this Is Nothing OrElse that Is Nothing Then
			Return False
		Else
			Return this.PublisherID = that.PublisherID
		End If
	End Function

	Public Overrides Function GetHashCode() As Integer
		Return PublisherID.GetHashCode
	End Function

	Public Overloads Function GetHashCode(other As PublisherData) As Integer 'Implements IEqualityComparer(Of SecretaryToolData.PublisherData).GetHashCode
		If other Is Nothing Then
			Return CType(0, Integer).GetHashCode
		Else
			Return other.PublisherID.GetHashCode
		End If
	End Function

	Shared _ActivePublishers As List(Of PublisherData)
	Friend Shared ReadOnly Property ActivePublishers As List(Of PublisherData)
		Get
			If _ActivePublishers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _ActivePublishers
		End Get
	End Property

	Shared _ActiveBaptizedPublishers As List(Of PublisherData)
	Friend Shared ReadOnly Property ActiveBaptizedPublishers As List(Of PublisherData)
		Get
			If _ActiveBaptizedPublishers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _ActiveBaptizedPublishers
		End Get
	End Property

	Shared _RegularPublishers As List(Of PublisherData)
	Friend Shared ReadOnly Property RegularPublishers As List(Of PublisherData)
		Get
			If _RegularPublishers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _RegularPublishers
		End Get
	End Property

	Shared _AuxiliaryPioneers As List(Of PublisherData)
	Friend Shared ReadOnly Property AuxiliaryPioneers As List(Of PublisherData)
		Get
			If _AuxiliaryPioneers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _AuxiliaryPioneers
		End Get
	End Property

	Shared _RegularPioneers As List(Of PublisherData)
	Friend Shared ReadOnly Property RegularPioneers As List(Of PublisherData)
		Get
			If _RegularPioneers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _RegularPioneers
		End Get
	End Property

	Shared _NewPublishers As List(Of PublisherData)
	Friend Shared ReadOnly Property NewPublishers As List(Of PublisherData)
		Get
			If _NewPublishers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _NewPublishers
		End Get
	End Property

	Shared _InactivePublishers As List(Of PublisherData)
	Friend Shared ReadOnly Property InactivePublishers As List(Of PublisherData)
		Get
			If _InactivePublishers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _InactivePublishers
		End Get
	End Property

	Shared _ReactivatedPublishers As List(Of PublisherData)
	Friend Shared ReadOnly Property ReactivatedPublishers As List(Of PublisherData)
		Get
			If _ReactivatedPublishers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _ReactivatedPublishers
		End Get
	End Property

	Shared _Elders As List(Of PublisherData)
	Friend Shared ReadOnly Property Elders As List(Of PublisherData)
		Get
			If _Elders Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _Elders
		End Get
	End Property

	Shared _MinisterialServants As List(Of PublisherData)
	Friend Shared ReadOnly Property MinisterialServants As List(Of PublisherData)
		Get
			If _MinisterialServants Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _MinisterialServants
		End Get
	End Property

	Shared _DeafPublishers As List(Of PublisherData)
	Friend Shared ReadOnly Property DeafPublishers As List(Of PublisherData)
		Get
			If _DeafPublishers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _DeafPublishers
		End Get
	End Property

	Shared _BlindPublishers As List(Of PublisherData)
	Friend Shared ReadOnly Property BlindPublishers As List(Of PublisherData)
		Get
			If _BlindPublishers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _BlindPublishers
		End Get
	End Property

	Shared _IrregularPublishers As List(Of PublisherData)
	Friend Shared ReadOnly Property IrregularPublishers As List(Of PublisherData)
		Get
			If _IrregularPublishers Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _IrregularPublishers
		End Get
	End Property

	Shared _MissingLastMonthsTime As List(Of PublisherData)
	Friend Shared ReadOnly Property MissingLastMonthsTime As List(Of PublisherData)
		Get
			If _MissingLastMonthsTime Is Nothing OrElse (Now.AddSeconds(-1)) > lastCalTime Then
				CalculateAnalysis()
			End If

			Return _MissingLastMonthsTime
		End Get
	End Property

	Public Shared ReadOnly Property PublishersMissingLastMonthsTime As List(Of VM_PublisherInformation)
		Get
			Return MissingLastMonthsTime.Select(Function(x) New VM_PublisherInformation(x.PublisherID)).ToList
		End Get
	End Property

	Private Shared Function _RecentPublishers() As List(Of PublisherData)
		Using db As New CongregationDataContainerLocal

			Dim myPublishers = From pubs In _LocalPublishers()
			  Group Join report In db.PublisherCardDatas
			  On pubs.PublisherID Equals report.PublisherID
			  Into RecentReports = Group
			Where RecentReports.Where(Function(x) x.EnteredUtc > ConfigPropertyKeys.ReportLastSubmitted.ToUniversalTime AndAlso Not x.IsHistorical).Count > 0
			 Select pubs

			Return myPublishers.ToList
		End Using
	End Function

	Public Shared ReadOnly Property RecentPublishers() As List(Of VM_PublisherInformation)
		Get
			Return _RecentPublishers.Select(Function(x) New VM_PublisherInformation(x.PublisherID)).ToList
		End Get
	End Property

	Private Shared Function _AllPublishers() As List(Of PublisherData)
		Using db As New CongregationDataContainerLocal
			Return db.PublisherDatas.ToList
		End Using
	End Function

	Public Shared ReadOnly Property AllPublishers As List(Of VM_PublisherInformation)
		Get
			Return _AllPublishers.Select(Function(x) New VM_PublisherInformation(x.PublisherID)).ToList
		End Get
	End Property

	Private Shared Function _LocalPublishers() As List(Of PublisherData)
		Using db As New CongregationDataContainerLocal
			Return db.PublisherDatas.Where(Function(x) Not x.IsMoveOut).ToList
		End Using
	End Function

	Public Shared ReadOnly Property LocalPublishers As List(Of VM_PublisherInformation)
		Get
			Return _LocalPublishers.Select(Function(x) New VM_PublisherInformation(x.PublisherID)).ToList
		End Get
	End Property

	'Public Shared Function NotYetReportedLastMonth() As List(Of PublisherData)
	'	Using db As New CongregationDataContainerLocal

	'		Return db.PublisherDatas.Where(Function(x) Not x.IsMoveOut AndAlso x.PublisherCardDatas.Where(Function(y) y.Month.Year & y.Month.Month <> Now.Year & Now.Month).Count = 0).ToList
	'	End Using

	'End Function

	Private Shared Function _ActivePublishersMissingReports() As List(Of PublisherData)
		Dim publishersMissingReports As New List(Of PublisherData)

		publishersMissingReports.AddRange(PublisherData.IrregularPublishers)
		publishersMissingReports.AddRange(PublisherData.MissingLastMonthsTime)
		publishersMissingReports = publishersMissingReports.Distinct.OrderBy(Function(x) x.FullName).ToList

		Return publishersMissingReports

	End Function

	Public Shared ReadOnly Property ActivePublishersMissingReports As List(Of VM_PublisherInformation)
		Get
			Return _ActivePublishersMissingReports.Select(Function(x) New VM_PublisherInformation(x.PublisherID)).ToList
		End Get
	End Property

	Private Shared Sub CalculateAnalysis()
		Using db As New CongregationDataContainerLocal

			Dim twelveMonthsAgo As Date = Now.AddMonths(-12).FirstOfTheMonth.AddDays(-1)
			Dim sixMonthsAgo As Date = Now.AddMonths(-6).FirstOfTheMonth.AddDays(-1)
			Dim lastMonth As Date = Now.FirstOfTheMonth

			Dim Publishers = From Publisher As PublisherData In PublisherData._LocalPublishers
			 Group Join pubTime As PublisherCardData In db.PublisherCardDatas
			 On Publisher.PublisherID Equals pubTime.PublisherID
			 Into PublishersTimeRecords = Group
			 Select Publisher,
			 SixMonthPublishersTimeRecords = PublishersTimeRecords.Where(Function(x) x.Month > sixMonthsAgo AndAlso x.Month < lastMonth),
			 PreviousSixMonthPublisherTimeRecord = PublishersTimeRecords.Where(Function(x) x.Month > twelveMonthsAgo AndAlso x.Month < sixMonthsAgo),
			 CurrentReportMonthTimeRecord = PublishersTimeRecords.Where(Function(x) x.Month = lastMonth.AddMonths(-1))

			Dim publishersSixMonthTotals = From pub In Publishers
			  Select Publisher = pub.Publisher,
			SixMonthPublishersTimeRecords = pub.SixMonthPublishersTimeRecords,
			PreviousSixMonthPublisherTimeRecord = pub.PreviousSixMonthPublisherTimeRecord,
			CurrentReportMonthTimeRecord = pub.CurrentReportMonthTimeRecord,
			  SixMonthTotal = pub.SixMonthPublishersTimeRecords.Sum(Function(x) x.Hours),
			PreviousSixMonthTotal = pub.PreviousSixMonthPublisherTimeRecord.Sum(Function(x) x.Hours)

			_ActivePublishers = publishersSixMonthTotals.Where(Function(x) x.SixMonthTotal > 0).Select(Function(x) x.Publisher).ToList
			_ActiveBaptizedPublishers = publishersSixMonthTotals.Where(Function(x) x.SixMonthTotal > 0 AndAlso x.Publisher.DateImmersed IsNot Nothing).Select(Function(x) x.Publisher).ToList
			_RegularPublishers = publishersSixMonthTotals.Where(Function(x) x.SixMonthPublishersTimeRecords.All(Function(y) y.Hours > 0)).Select(Function(x) x.Publisher).ToList
			_AuxiliaryPioneers = publishersSixMonthTotals.Where(Function(x) x.SixMonthPublishersTimeRecords.Any(Function(y) y.IsAuxPioneer)).Select(Function(x) x.Publisher).ToList
			_RegularPioneers = publishersSixMonthTotals.Where(Function(x) x.SixMonthPublishersTimeRecords.Any(Function(y) y.IsPioneer)).Select(Function(x) x.Publisher).ToList
			_NewPublishers = publishersSixMonthTotals.Where(Function(x) x.Publisher.IsMoveIn = False AndAlso x.Publisher.BeganPublishing > sixMonthsAgo).Select(Function(x) x.Publisher).ToList
			_InactivePublishers = publishersSixMonthTotals.Where(Function(x) x.SixMonthTotal = 0).Select(Function(x) x.Publisher).ToList
			_ReactivatedPublishers = publishersSixMonthTotals.Where(Function(x) x.PreviousSixMonthTotal = 0 AndAlso x.SixMonthTotal > 0).Select(Function(x) x.Publisher).ToList
			_Elders = publishersSixMonthTotals.Where(Function(x) x.Publisher.IsElder).Select(Function(x) x.Publisher).ToList
			_MinisterialServants = publishersSixMonthTotals.Where(Function(x) x.Publisher.IsMinisterialServant).Select(Function(x) x.Publisher).ToList
			_DeafPublishers = publishersSixMonthTotals.Where(Function(x) x.Publisher.IsDeaf).Select(Function(x) x.Publisher).ToList
			_BlindPublishers = publishersSixMonthTotals.Where(Function(x) x.Publisher.IsBlind).Select(Function(x) x.Publisher).ToList

			'if a person didn't report 6 months of time in the past 6 months, they will show as irregular
			_IrregularPublishers = publishersSixMonthTotals.Where(Function(x) x.SixMonthPublishersTimeRecords.Count < 6).Select(Function(x) x.Publisher).ToList

			_MissingLastMonthsTime = publishersSixMonthTotals.Where(Function(x) x.CurrentReportMonthTimeRecord.Count = 0 OrElse x.CurrentReportMonthTimeRecord.Where(Function(y) y.Hours = 0).Count > 0).Select(Function(x) x.Publisher).ToList
		End Using

		lastCalTime = Now
	End Sub

	Friend Shared Function _ReportingPublishers() As List(Of PublisherData)
		Using db As New CongregationDataContainerLocal

			Dim myPublishers = From pubs In _LocalPublishers()
			 Group Join reports In db.PublisherCardDatas
			 On pubs.PublisherID Equals reports.PublisherID
			 Into PubReports = Group
			 Select pubs,
			  RecentReports = PubReports.Where(Function(x) Not x.IsHistorical AndAlso Not x.IsAuxPioneer AndAlso Not x.IsPioneer AndAlso Not x.IsSpecialPioneer AndAlso Not x.Reported).ToList

			Return myPublishers.Where(Function(x) x.RecentReports.Count > 0).Select(Function(x) x.pubs).ToList
		End Using
	End Function

	Friend Shared Function _ReportingAuxPioneers() As List(Of PublisherData)
		Using db As New CongregationDataContainerLocal

			Dim myPublishers = From pubs In _LocalPublishers()
			 Group Join reports In db.PublisherCardDatas
			 On pubs.PublisherID Equals reports.PublisherID
			 Into PubReports = Group
			 Select pubs,
			  RecentReports = PubReports.Where(Function(x) Not x.IsHistorical AndAlso x.IsAuxPioneer AndAlso Not x.IsPioneer AndAlso Not x.IsSpecialPioneer AndAlso Not x.Reported)

			Return myPublishers.Where(Function(x) x.RecentReports.Count > 0)
		End Using
	End Function

	Friend Shared Function _ReportingPioneers() As List(Of PublisherData)
		Using db As New CongregationDataContainerLocal

			Dim myPublishers = From pubs In _LocalPublishers()
			 Group Join reports In db.PublisherCardDatas
			 On pubs.PublisherID Equals reports.PublisherID
			 Into PubReports = Group
			 Select pubs,
			  RecentReports = PubReports.Where(Function(x) Not x.IsHistorical AndAlso Not x.IsAuxPioneer AndAlso x.IsPioneer AndAlso Not x.IsSpecialPioneer AndAlso Not x.Reported)

			Return myPublishers.Where(Function(x) x.RecentReports.Count > 0)
		End Using
	End Function

	Friend Shared Function _SinglePublisher(PublisherID As Long) As PublisherData
		Using db As New CongregationDataContainerLocal

			Return db.PublisherDatas.Single(Function(x) x.PublisherID = PublisherID)
		End Using
	End Function

	Friend Shared Sub _AddToPublisherDatas(Publisher As PublisherData)
		Using db As New CongregationDataContainerLocal

			db.AddToPublisherDatas(Publisher)
			db.SaveChanges()
		End Using
	End Sub

	Friend Shared Function _FamilyHeads() As List(Of PublisherData)
		Return _LocalPublishers.Where(Function(x) x.IsFamilyHead).ToList
	End Function

	Public Shared ReadOnly Property FamilyHeads As List(Of VM_PublisherInformation)
		Get
			Return _FamilyHeads.Select(Function(x) New VM_PublisherInformation(x.PublisherID)).ToList
		End Get
	End Property

	Friend Shared Function _GroupOverseers() As List(Of PublisherData)
		Using db As New CongregationDataContainerLocal
			Dim listOfGroups As New List(Of Long)
			Dim listOfOverseers As New List(Of PublisherData)
			'Return db.PublisherDatas.Where(Function(x) x.IsFamilyHead And Not x.IsMoveOut).ToList
			'listOfGroups.AddRange(db.PublisherDatas.Select(Function(x) x.GroupID).Distinct.ToList)

			'For Each myGroup In db.Groups.Where(Function(x) x.PublisherDatas.Count > 0)
			'	Dim linqMyGroup = myGroup
			'	listOfOverseers.AddRange(db.PublisherDatas.Select(Function(x) linqMyGroup.PublisherData.PublisherID = x.PublisherID OrElse linqMyGroup.PublisherData1.PublisherID = x.PublisherID))
			'Next

			listOfOverseers.AddRange(db.Groups.Select(Function(x) x.PublisherData))
			listOfOverseers.AddRange(db.Groups.Select(Function(x) x.PublisherData1))

			Return listOfOverseers
		End Using
	End Function

	Public Shared ReadOnly Property GroupOverseers As List(Of VM_PublisherInformation)
		Get
			Return _GroupOverseers.Select(Function(x) New VM_PublisherInformation(x.PublisherID)).ToList
		End Get
	End Property

End Class